package server

import (
	"fmt"
	"sync"
)

// 定义参数结构体
type Params struct {
	// 字段定义
}

// 定义 结构体
type ForRangeChannel struct{}

//报错：fatal error: all goroutines are asleep - deadlock!
func (f ForRangeChannel) ForRangeChannel1(params *Params) (*Params, error) {
	ch := make(chan struct{})
	defer close(ch)

	go func() {
		ch <- struct{}{}
	}()

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 不使用 for range ch
// 成功
func (f ForRangeChannel) ForRangeChannel2(params *Params) (*Params, error) {
	ch := make(chan struct{})
	defer close(ch)

	go func() {
		ch <- struct{}{}
	}()

	i := 0
	<-ch // 直接接收一次数据
	i++

	fmt.Printf("%d", i)
	return nil, nil
}

// 改成多次发送数据
// fatal error: all goroutines are asleep - deadlock!
func (f ForRangeChannel) ForRangeChannel3(params *Params) (*Params, error) {
	ch := make(chan struct{})
	defer close(ch)

	go func() {
		for i := 0; i < 5; i++ { // 发送多次数据
			ch <- struct{}{}
		}
	}()

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 使用带缓冲区的通道
// fatal error: all goroutines are asleep - deadlock!
func (f ForRangeChannel) ForRangeChannel4(params *Params) (*Params, error) {
	ch := make(chan struct{}, 1) // 添加缓冲区
	defer close(ch)

	go func() {
		ch <- struct{}{}
	}()

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 使用 sync.WaitGroup 来协调 goroutine
// fatal error: all goroutines are asleep - deadlock!
func (f ForRangeChannel) ForRangeChannel5(params *Params) (*Params, error) {
	var wg sync.WaitGroup
	wg.Add(1)

	ch := make(chan struct{})

	go func() {
		defer wg.Done()
		ch <- struct{}{}
	}()

	wg.Wait() // 等待 goroutine 完成
	close(ch)

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 避免使用 for range
// 成功
func (f ForRangeChannel) ForRangeChannel6(params *Params) (*Params, error) {
	ch := make(chan struct{})
	defer close(ch)

	go func() {
		ch <- struct{}{}
	}()

	i := 0
	select {
	case <-ch:
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 成功
func (f ForRangeChannel) ForRangeChannel7(params *Params) (*Params, error) {
	ch := make(chan struct{})

	go func() {
		defer close(ch)
		//for i := 0; i < 5; i++ {
		ch <- struct{}{}
		//}
	}()

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 成功
func (f ForRangeChannel) ForRangeChannel8(params *Params) (*Params, error) {
	ch := make(chan struct{}, 1)

	go func() {
		defer close(ch)
		for i := 0; i < 5; i++ {
			ch <- struct{}{}
		}
	}()

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 2--- PASS: TestForRangeChannel9 (0.00s)
func (f ForRangeChannel) ForRangeChannel9(params *Params) (*Params, error) {
	var wg sync.WaitGroup
	ch := make(chan struct{}, 2)

	wg.Add(1)
	go func() {
		defer wg.Done()
		ch <- struct{}{}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		ch <- struct{}{}
	}()

	wg.Wait() // 等待 goroutine 完成
	close(ch)

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// fatal error: all goroutines are asleep - deadlock!
func (f ForRangeChannel) ForRangeChannel10(params *Params) (*Params, error) {
	var wg sync.WaitGroup
	ch := make(chan struct{}, 1)

	wg.Add(1)
	go func() {
		defer wg.Done()
		//defer wg.Done()
		ch <- struct{}{}
		ch <- struct{}{}
	}()

	wg.Wait() // 等待 goroutine 完成
	close(ch)

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}

// 1--- PASS
func (f ForRangeChannel) ForRangeChannel11(params *Params) (*Params, error) {
	var wg sync.WaitGroup
	ch := make(chan struct{}, 3)

	wg.Add(1)
	go func() {
		defer wg.Done()
		ch <- struct{}{}
	}()

	wg.Wait() // 等待 goroutine 完成
	close(ch)

	i := 0
	for range ch {
		i++
	}

	fmt.Printf("%d", i)
	return nil, nil
}
